// Include Files
#include "Definitions.h"
#include "String.h"

/////////////////////////////////////////////////////////////////////////////////////
// string_t Implementation

IE::string_t::string_t() : m_uLength(0), m_szData(NULL) { }

IE::string_t::string_t( char_t _cText )
{
	// the first character is given, the second is a null terminator
	m_uLength = 2;
	m_szData = new char_t[m_uLength];
	m_szData[0] = _cText;
	m_szData[1] = '\0';
}

IE::string_t::string_t( char_t const * const _szText )
{
	if( _szText )
	{
		// copy the character array
		m_uLength = (uint_t)wcslen(_szText) + 1;
		m_szData = new char_t[m_uLength];
		memcpy( m_szData, _szText, m_uLength * sizeof( char_t ) );
	}
	else
	{
		// no data
		m_uLength = 0;
		m_szData = NULL;
	}
}

IE::string_t::string_t( string_t const & _strText )
{
	if( _strText.m_uLength )
	{
		// copy the string
		m_uLength = _strText.m_uLength;
		m_szData = new char_t[m_uLength];
		memcpy( m_szData, _strText.m_szData, m_uLength * sizeof( char_t ) );
	}
	else
	{
		// no data
		m_uLength = 0;
		m_szData = NULL;
	}
}

IE::string_t::string_t( char const * const _szText )
{
	if( _szText )
	{
		// convert the character array to unicode
		m_uLength = (uint_t)strlen(_szText) + 1;
		m_szData = new char_t[m_uLength];
		MultiByteToWideChar(0, 0, _szText, m_uLength, m_szData, m_uLength);
	}
	else
	{
		// no data
		m_uLength = 0;
		m_szData = NULL;
	}
}

IE::string_t IE::string_t::Substring( uint_t _uStart )
{
	string_t strRet;

	strRet.m_uLength = m_uLength - _uStart;
	strRet.m_szData = new char_t[strRet.m_uLength];
	memcpy( 
		strRet.m_szData, m_szData + _uStart, strRet.m_uLength * sizeof(char_t) 
	);

	return strRet;
}

IE::string_t IE::string_t::Substring( uint_t _uStart, uint_t _uLength )
{
	string_t strRet;

	strRet.m_uLength = _uLength + 1;
	strRet.m_szData = new char_t[strRet.m_uLength];
	memcpy( strRet.m_szData, m_szData + _uStart, _uLength * sizeof(char_t) );
	strRet.m_szData[_uLength] = '\0';

	return strRet;
}

IE::int_t IE::string_t::IndexOf( char_t _cSearch )
{
	for( uint_t u = 0; u < m_uLength; ++u )
	{
		if( m_szData[u] == _cSearch )
		{
			return (int)u;
		}
	}
	return -1;
}

IE::int_t IE::string_t::IndexOf( char_t _cSearch, uint_t _uStart )
{
	for( uint_t u = _uStart; u < m_uLength; ++u )
	{
		if( m_szData[u] == _cSearch )
		{
			return (int)u;
		}
	}
	return -1;
}

IE::int_t IE::string_t::LastIndexOf( char_t _cSearch )
{
	for( uint_t u = m_uLength - 1; u >= 0; --u )
	{
		if( m_szData[u] == _cSearch )
		{
			return (int)u;
		}
	}
	return -1;
}

IE::int_t IE::string_t::LastIndexOf( char_t _cSearch, uint_t _uStart )
{
	for( uint_t u = _uStart; u >= 0; --u )
	{
		if( m_szData[u] == _cSearch )
		{
			return (int)u;
		}
	}
	return -1;
}

IE::string_t &IE::string_t::operator =( char_t _cText )
{
	// get rid of the old string
	if(m_szData) delete[] m_szData;

	// the first character is given, the second is a null terminator
	m_uLength = 2;
	m_szData = new char_t[m_uLength];
	m_szData[0] = _cText;
	m_szData[1] = '\0';
	return *this;
}

IE::string_t &IE::string_t::operator =( char_t const * const _szText )
{
	// get rid of the old string
	if(m_szData) delete[] m_szData;

	if( _szText )
	{
		// copy the character array
		m_uLength = (uint_t)wcslen(_szText) + 1;
		m_szData = new char_t[m_uLength];
		memcpy( m_szData, _szText, m_uLength * sizeof(char_t) );
	}
	else
	{
		// no data
		m_uLength = 0;
		m_szData = NULL;
	}

	return *this;
}

IE::string_t &IE::string_t::operator =( string_t const & _strText )
{
	// check for self-assignment
	if( this != &_strText )
	{
		// get rid of the old string
		if(m_szData) delete[] m_szData;

		if( _strText.m_szData )
		{
			// copy the string
			m_uLength = _strText.m_uLength;
			m_szData = new char_t[m_uLength];
			memcpy( m_szData, _strText.m_szData, m_uLength * sizeof(char_t) );
		}
		else
		{
			// no data
			m_uLength = 0;
			m_szData = NULL;
		}
	}

	return *this;
}

IE::string_t IE::string_t::operator +( char_t _cText )
{
	(void)_cText;

	// TODO
	assert(FALSE);
	return string_t(_cText);
}

IE::string_t IE::string_t::operator +( char_t const *_szText )
{
	(void)_szText;

	// TODO
	assert(FALSE);
	return string_t(_szText);
}

IE::string_t IE::string_t::operator +( string_t const &_strText )
{
	(void)_strText;

	// TODO
	assert(FALSE);
	return string_t(_strText);
}

IE::string_t IE::operator +( char_t _cText, string_t const &_strText )
{
	(void)_cText; (void)_strText;

	// TODO
	assert(FALSE);
	return string_t(_cText);
}

IE::string_t IE::operator +( char_t const *_szText, string_t const &_strText )
{
	string_t strResult;

	uint_t uLHSLength = (uint_t)wcslen(_szText);
	uint_t uRHSLength = _strText.m_uLength;

	strResult.m_uLength = uLHSLength + uRHSLength;
	strResult.m_szData = new char_t[strResult.m_uLength];

	memcpy(strResult.m_szData, _szText, uLHSLength * 2);
	memcpy(strResult.m_szData + uLHSLength, _strText.m_szData, uRHSLength * 2);

	return strResult;
}

IE::string_t & IE::string_t::operator +=( char_t _cText )
{
	(void)_cText;

	// TODO
	assert(FALSE);
	return *this;
}

IE::string_t & IE::string_t::operator +=( char_t const *_szText )
{
	(void)_szText;

	// TODO
	assert(FALSE);
	return *this;
}

IE::string_t & IE::string_t::operator +=( string_t const &_strText )
{
	(void)_strText;

	// TODO
	assert(FALSE);
	return *this;
}

IE::bool_t IE::string_t::operator ==( char_t _cText )
{
	return m_uLength == 2 && m_szData[0] == _cText;
}

IE::bool_t IE::string_t::operator ==( char_t const * _szText )
{
	// if the lengths are different, they are different
	uint_t uiLength = (uint_t)wcslen(_szText) + 1;
	if( uiLength != m_uLength ) return false;

	// if any character is different, they are different
	for( uint_t i = 0; i < uiLength; ++i )
	{
		if( m_szData[i] != _szText[i] ) return false;
	}

	// everything was the same
	return true;
}

IE::bool_t IE::string_t::operator ==( string_t const & _strText )
{
	// if the lengths are different, they are different
	if( m_uLength != _strText.m_uLength ) return false;

	// if any character is different, they are different
	for( uint_t i = 0; i < m_uLength; ++i )
	{
		if( m_szData[i] != _strText.m_szData[i] ) return false;
	}

	// everything was the same
	return true;
}

IE::bool_t IE::operator ==( char_t _cText, string_t const & _strText )
{
	return _strText.m_uLength == 2 && _strText.m_szData[0] == _cText;
}

IE::bool_t IE::operator ==( char_t const * _szText, string_t const & _strText )
{
	// if the lengths are different, they are different
	uint_t uiLength = (uint_t)wcslen(_szText) + 1;
	if( uiLength != _strText.m_uLength ) return false;

	// if any character is different, they are different
	for( uint_t i = 0; i < uiLength; ++i )
	{
		if( _strText.m_szData[i] != _szText[i] ) return false;
	}

	// everything was the same
	return true;
}

IE::bool_t IE::string_t::operator !=( char_t _cText )
{
	(void)_cText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator !=( char_t const * _szText )
{
	(void)_szText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator !=( string_t const & _strText )
{
	(void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::operator !=( char_t _cText, string_t const & _strText )
{
	(void)_cText; (void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::operator !=( char_t const * _szText, string_t const & _strText )
{
	(void)_szText; (void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator >( char_t _cText )
{
	(void)_cText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator >( char_t const * _szText )
{
	(void)_szText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator >( string_t const & _strText )
{
	(void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::operator >( char_t _cText, string_t const & _strText )
{
	(void)_cText; (void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::operator >( char_t const * _szText, string_t const & _strText )
{
	(void)_szText; (void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator <( char_t _cText )
{
	(void)_cText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator <( char_t const * _szText )
{
	(void)_szText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator <( string_t const & _strText )
{
	(void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::operator <( char_t _cText, string_t const & _strText )
{
	(void)_cText; (void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::operator <( char_t const * _szText, string_t const & _strText )
{
	(void)_szText; (void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator >=( char_t _cText )
{
	(void)_cText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator >=( char_t const * _szText )
{
	(void)_szText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator >=( string_t const & _strText )
{
	(void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::operator >=( char_t _cText, string_t const & _strText )
{
	(void)_cText; (void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::operator >=( char_t const * _szText, string_t const & _strText )
{
	(void)_szText; (void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator <=( char_t _cText )
{
	(void)_cText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator <=( char_t const * _szText )
{
	(void)_szText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::string_t::operator <=( string_t const & _strText )
{
	(void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::operator <=( char_t _cText, string_t const & _strText )
{
	(void)_cText; (void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}

IE::bool_t IE::operator <=( char_t const * _szText, string_t const & _strText )
{
	(void)_szText; (void)_strText;

	// TODO
	assert(FALSE);
	return FALSE;
}
